package com.example.teesystem.service.impl;

import cn.hutool.core.lang.Validator;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.teesystem.common.cache.UserCache;
import com.example.teesystem.common.utils.CustomConvert;
import com.example.teesystem.common.utils.Response;
import com.example.teesystem.entity.Class;
import com.example.teesystem.entity.ClassStudent;
import com.example.teesystem.entity.User;
import com.example.teesystem.entity.vo.*;
import com.example.teesystem.entity.vo.clazz.*;
import com.example.teesystem.entityDto.ClassEvaluate;
import com.example.teesystem.entityDto.RadarEvaluate;
import com.example.teesystem.entityDto.UserList;
import com.example.teesystem.mapper.*;
import com.example.teesystem.service.ClassService;
import com.example.teesystem.service.IssueRecordService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.*;

/**
* @author 28131
* @description 针对表【t_class】的数据库操作Service实现
* @createDate 2022-03-28 11:46:43
*/
@Service
@RequiredArgsConstructor
public class ClassServiceImpl extends ServiceImpl<ClassMapper, Class>
    implements ClassService{
    private final ClassMapper classMapper;
    private final ClassStudentMapper classStudentMapper;
    private final UserMapper userMapper;
    private final AdvancedTrainingProgressMapper advancedTrainingProgressMapper;
    private final AdvancedTrainingMapper advancedTrainingMapper;
    private final IssueRecordService issueRecordService;
    
    @Override
    public boolean add(ClassUploadVo classUploadVo) {
        Class aClass = new Class();
        BeanUtils.copyProperties(classUploadVo, aClass);
        if(Validator.isNotNull(classUploadVo.getOpen())) {
            aClass.setOpen(CustomConvert.convertToString(classUploadVo.getOpen()));
        }
        return this.save(aClass);
    }
    
    @Override
    public boolean update(ClassUpdateVo classUpdateVo) {
        Class aClass = new Class();
        BeanUtils.copyProperties(classUpdateVo, aClass);
        if(classUpdateVo.getOpen() != null) {
            aClass.setOpen(CustomConvert.convertToString(classUpdateVo.getOpen()));
        }
        return this.updateById(aClass);
    }
    
    @Override
    public PageResponseVo<ClassResponseVo> getClasses(ClassSelectVo classSelectVo) {
        // 条件查询
        QueryWrapper<Class> wrapper = new QueryWrapper<>();
        wrapper.eq("course_id", classSelectVo.getCourseId())
                .like(Validator.isNotEmpty(classSelectVo.getClassName()), "class_name", classSelectVo.getClassName());
        Page<Class> classPage = new Page<>(classSelectVo.getPageConfig().getCur(), classSelectVo.getPageConfig().getSize());
        Page<Class> result = this.page(classPage, wrapper);
        List<Class> classes = result.getRecords();
        
        // 数据封装转化
        ArrayList<ClassResponseVo> classResponseVos = new ArrayList<>();
        classes.forEach(aClass -> {
            ClassResponseVo classResponseVo = new ClassResponseVo();
            BeanUtils.copyProperties(aClass, classResponseVo);
            String name = UserCache.userMap.getOrDefault(aClass.getTeacherId(), UserCache.NONE_USER).getMyName();
            classResponseVo.setTeacherName(name != null ? name : "用户不存在");
            classResponseVo.setOpen(CustomConvert.convertToList(aClass.getOpen()));
            QueryWrapper<ClassStudent> wrapper1 = new QueryWrapper<>();
            wrapper1.eq("class_id", classResponseVo.getId());
            classResponseVo.setStudentsCount(Math.toIntExact(classStudentMapper.selectCount(wrapper1)));
            
            classResponseVos.add(classResponseVo);
        });
    
        return new PageResponseVo<>(classResponseVos, result.getCurrent(), result.getSize(), result.getPages());
    }

    @Override
    public int getCourseId(int id) {
        try{
            return classMapper.getCourseId(id);
        }catch (Exception e){
            return 0;
        }
    }
    
    @Override
    public boolean delete(ClassDeleteVo classDeleteVo) {
        QueryWrapper<ClassStudent> studentQueryWrapper = new QueryWrapper<>();
        studentQueryWrapper.eq("class_id", classDeleteVo.getId());
        if(!classDeleteVo.getCascadeDelete()) {
            if(classStudentMapper.selectCount(studentQueryWrapper) > 0) {
                return false;
            }
            return this.removeById(classDeleteVo.getId());
        }
        classStudentMapper.delete(studentQueryWrapper);
        return this.removeById(classDeleteVo.getId());
    }

    @Override
    public Response classEvaluate(int courseId) {
        List<Class> classes = classMapper.getClassesByCourse(courseId);
        List<ClassEvaluate> classEvaluates = new ArrayList<>();
        int adTainingNum = 0;
        if(advancedTrainingMapper.getAllNum(courseId)!=null){
            adTainingNum = advancedTrainingMapper.getAllNum(courseId);
        }

        for(Class myClass:classes){
            //过度量
            List<Integer> studentIds = classStudentMapper.getStudentIdByClassId(myClass.getId());
            if(studentIds.size()==0|| studentIds==null) {
                continue;
            }
            List<User> users = userMapper.getUsersByIds(studentIds);
            int allLoginCount = 0;
            int first = users.get(0).getId(),last = users.get(0).getId(),max = 0,min = Integer.MAX_VALUE,adTotal = 0;
            List<RadarEvaluate> radarEvaluates = new ArrayList<>();

            //返回量
            int loginPercentCount;
            List<UserList> loginFirstThreeLists = new ArrayList<>();
            UserList adTrainingFirst;
            List<UserList> loginLastThreeLists = new ArrayList<>();
            UserList adTrainingLast;
            double adPercent = 0.0;
            List<UserList> problemStudent = new ArrayList<>();
            List<UserList> goodStudent = new ArrayList<>();
            ClassEvaluate classEvaluate = new ClassEvaluate();


            Collections.sort(users);

            Map<Integer,User> map = new HashMap<>();
            for(User user:users){
                map.put(user.getId(),user);
                allLoginCount = allLoginCount + user.getCount();
            }

            //登录次数处理
            loginPercentCount = (int) (allLoginCount/users.size());
            if(users.size()>3){
                loginFirstThreeLists.add(new UserList(users.get(0)));
                loginFirstThreeLists.add(new UserList(users.get(1)));
                loginFirstThreeLists.add(new UserList(users.get(2)));

                loginLastThreeLists.add(new UserList(users.get(users.size()-1)));
                loginLastThreeLists.add(new UserList(users.get(users.size()-2)));
                loginLastThreeLists.add(new UserList(users.get(users.size()-3)));
            }
            else {
                for(User user:users){
                    loginFirstThreeLists.add(new UserList(user));
                    loginLastThreeLists.add(new UserList(user));
                }
            }

            //进阶训练
            for(User user:users){
                int num = 0;
                if(advancedTrainingProgressMapper.getAnswerNum(courseId,user.getId()) != null) {
                    num = advancedTrainingProgressMapper.getAnswerNum(courseId,user.getId());
                }

                if(num >= max){
                    first = user.getId();
                    max = num;
                }else if(num <= min){
                    last = user.getId();
                    min = num;
                }
                adTotal = adTotal + num;
            }



            adPercent = Double.valueOf(adTotal)/Double.valueOf(adTainingNum);
            adTrainingFirst = new UserList(map.get(first));
            adTrainingLast = new UserList(map.get(last));

            //学习能力
            for(User user:users){
                Map<String,Double> radarMap = issueRecordService.getStudentRadar(courseId,user.getId());
                RadarEvaluate radarEvaluate = new RadarEvaluate(radarMap.get("记忆型"),radarMap.get("理解型"),radarMap.get("应用型"),radarMap.get("逻辑型"),radarMap.get("概念型"),radarMap.get("综合型"),user.getId());
                if(radarEvaluate.getPercent()<0.15){
                    problemStudent.add(new UserList(user));
                }
                radarEvaluates.add(radarEvaluate);
            }

            Collections.sort(radarEvaluates);

            if(radarEvaluates.size()>3){
                goodStudent.add(new UserList(map.get(radarEvaluates.get(0).getUid())));
                goodStudent.add(new UserList(map.get(radarEvaluates.get(1).getUid())));
                goodStudent.add(new UserList(map.get(radarEvaluates.get(2).getUid())));
            }else {
                for(RadarEvaluate radarEvaluate:radarEvaluates){
                    goodStudent.add(new UserList(map.get(radarEvaluate.getUid())));
                }
            }

            classEvaluate.setLoginPercentCount(loginPercentCount);
            classEvaluate.setLoginFirstThreeLists(loginFirstThreeLists);
            classEvaluate.setAdTrainingFirst(adTrainingFirst);
            classEvaluate.setLoginLastThreeLists(loginLastThreeLists);
            classEvaluate.setAdTrainingLast(adTrainingLast);
            classEvaluate.setAdPercent(adPercent);
            classEvaluate.setProblemStudent(problemStudent);
            classEvaluate.setMyClass(myClass);
            classEvaluate.setGoodStudent(goodStudent);

            classEvaluates.add(classEvaluate);

        }
        return Response.ok(classEvaluates);
    }
}
